<template>
  <div class="apple-pagination" :class="paginationClass">
    <!-- 总计信息 -->
    <div v-if="showTotal" class="apple-pagination__total">
      <slot name="total" :total="total" :range="currentRange">
        显示第 {{ currentRange.start }} - {{ currentRange.end }} 条，共 {{ total }} 条
      </slot>
    </div>

    <!-- 分页控件 -->
    <div class="apple-pagination__controls">
      <!-- 页码大小选择器 -->
      <div v-if="showSizeChanger" class="apple-pagination__size-changer">
        <span class="apple-pagination__size-label">每页</span>
        <AppleSelect
          v-model="internalPageSize"
          :options="pageSizeOptions"
          size="small"
          class="apple-pagination__size-select"
          @change="handlePageSizeChange"
        />
        <span class="apple-pagination__size-label">条</span>
      </div>

      <!-- 快速跳转 -->
      <div v-if="showQuickJumper && totalPages > 1" class="apple-pagination__jumper">
        <span class="apple-pagination__jumper-label">跳至</span>
        <AppleInput
          v-model="jumpValue"
          type="number"
          size="small"
          :min="1"
          :max="totalPages"
          class="apple-pagination__jumper-input"
          @keydown.enter="handleJump"
          @blur="handleJump"
        />
        <span class="apple-pagination__jumper-label">页</span>
      </div>

      <!-- 页码导航 -->
      <div class="apple-pagination__nav">
        <!-- 上一页 -->
        <button
          class="apple-pagination__btn apple-pagination__btn--prev"
          :class="{ 'apple-pagination__btn--disabled': current <= 1 }"
          :disabled="current <= 1"
          @click="handlePrevPage"
          :aria-label="prevAriaLabel"
        >
          <svg viewBox="0 0 20 20" fill="currentColor">
            <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
          </svg>
          <span v-if="showText">{{ prevText }}</span>
        </button>

        <!-- 页码列表 -->
        <div class="apple-pagination__pages">
          <!-- 第一页 -->
          <button
            v-if="showFirstLast && current > showRange + 1"
            class="apple-pagination__btn apple-pagination__btn--page"
            @click="handlePageChange(1)"
          >
            1
          </button>

          <!-- 前省略号 -->
          <span
            v-if="showFirstLast && current > showRange + 2"
            class="apple-pagination__ellipsis"
          >
            ...
          </span>

          <!-- 页码按钮 -->
          <button
            v-for="page in visiblePages"
            :key="page"
            class="apple-pagination__btn apple-pagination__btn--page"
            :class="{ 'apple-pagination__btn--current': page === current }"
            @click="handlePageChange(page)"
          >
            {{ page }}
          </button>

          <!-- 后省略号 -->
          <span
            v-if="showFirstLast && current < totalPages - showRange - 1"
            class="apple-pagination__ellipsis"
          >
            ...
          </span>

          <!-- 最后一页 -->
          <button
            v-if="showFirstLast && current < totalPages - showRange"
            class="apple-pagination__btn apple-pagination__btn--page"
            @click="handlePageChange(totalPages)"
          >
            {{ totalPages }}
          </button>
        </div>

        <!-- 下一页 -->
        <button
          class="apple-pagination__btn apple-pagination__btn--next"
          :class="{ 'apple-pagination__btn--disabled': current >= totalPages }"
          :disabled="current >= totalPages"
          @click="handleNextPage"
          :aria-label="nextAriaLabel"
        >
          <span v-if="showText">{{ nextText }}</span>
          <svg viewBox="0 0 20 20" fill="currentColor">
            <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
          </svg>
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import AppleSelect from './AppleSelect.vue'
import AppleInput from './AppleInput.vue'

export interface ApplePaginationProps {
  current: number
  total: number
  pageSize?: number
  pageSizeOptions?: number[]
  size?: 'small' | 'medium' | 'large'
  simple?: boolean
  showTotal?: boolean
  showSizeChanger?: boolean
  showQuickJumper?: boolean
  showFirstLast?: boolean
  showText?: boolean
  showRange?: number
  hideOnSinglePage?: boolean
  prevText?: string
  nextText?: string
  prevAriaLabel?: string
  nextAriaLabel?: string
  customClass?: string
}

const props = withDefaults(defineProps<ApplePaginationProps>(), {
  pageSize: 10,
  pageSizeOptions: () => [10, 20, 50, 100],
  size: 'medium',
  simple: false,
  showTotal: true,
  showSizeChanger: true,
  showQuickJumper: true,
  showFirstLast: true,
  showText: false,
  showRange: 2,
  hideOnSinglePage: false,
  prevText: '上一页',
  nextText: '下一页',
  prevAriaLabel: '上一页',
  nextAriaLabel: '下一页',
  customClass: ''
})

const emit = defineEmits<{
  'update:current': [page: number]
  'update:pageSize': [size: number]
  'change': [page: number, pageSize: number]
  'showSizeChange': [current: number, size: number]
}>()

// 内部状态
const internalPageSize = ref(props.pageSize)
const jumpValue = ref('')

// 计算属性
const totalPages = computed(() => Math.ceil(props.total / internalPageSize.value))

const paginationClass = computed(() => [
  `apple-pagination--${props.size}`,
  {
    'apple-pagination--simple': props.simple,
    'apple-pagination--hidden': props.hideOnSinglePage && totalPages.value <= 1,
  },
  props.customClass
])

const currentRange = computed(() => {
  const start = (props.current - 1) * internalPageSize.value + 1
  const end = Math.min(props.current * internalPageSize.value, props.total)
  return { start, end }
})

const visiblePages = computed(() => {
  const pages: number[] = []
  const range = props.showRange
  let start = Math.max(1, props.current - range)
  let end = Math.min(totalPages.value, props.current + range)

  // 调整范围以显示足够的页码
  if (end - start < range * 2) {
    if (start === 1) {
      end = Math.min(totalPages.value, start + range * 2)
    } else if (end === totalPages.value) {
      start = Math.max(1, end - range * 2)
    }
  }

  for (let i = start; i <= end; i++) {
    pages.push(i)
  }

  return pages
})

const pageSizeOptions = computed(() => {
  return props.pageSizeOptions.map(size => ({
    label: String(size),
    value: size
  }))
})

// 事件处理
const handlePageChange = (page: number) => {
  if (page < 1 || page > totalPages.value || page === props.current) return
  
  emit('update:current', page)
  emit('change', page, internalPageSize.value)
}

const handlePrevPage = () => {
  handlePageChange(props.current - 1)
}

const handleNextPage = () => {
  handlePageChange(props.current + 1)
}

const handlePageSizeChange = (newSize: number) => {
  internalPageSize.value = newSize
  
  // 计算新的页码，确保数据连续性
  const newPage = Math.ceil(((props.current - 1) * props.pageSize + 1) / newSize)
  const clampedPage = Math.min(newPage, Math.ceil(props.total / newSize))
  
  emit('update:pageSize', newSize)
  emit('update:current', clampedPage)
  emit('change', clampedPage, newSize)
  emit('showSizeChange', clampedPage, newSize)
}

const handleJump = () => {
  const page = parseInt(jumpValue.value)
  if (isNaN(page) || page < 1 || page > totalPages.value) {
    jumpValue.value = ''
    return
  }
  
  handlePageChange(page)
  jumpValue.value = ''
}

// 监听器
watch(() => props.pageSize, (newSize) => {
  if (newSize !== internalPageSize.value) {
    internalPageSize.value = newSize
  }
})
</script>

<style lang="scss" scoped>
.apple-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: 14px;
  color: var(--apple-color-text-primary);

  &--small {
    font-size: 12px;
    gap: 12px;
  }

  &--large {
    font-size: 16px;
    gap: 20px;
  }

  &--simple {
    .apple-pagination__pages {
      display: none;
    }
  }

  &--hidden {
    display: none;
  }

  @media (max-width: 768px) {
    flex-direction: column;
    gap: 12px;
  }
}

.apple-pagination__total {
  color: var(--apple-color-text-secondary);
  font-size: inherit;
  
  @media (max-width: 768px) {
    order: 2;
  }
}

.apple-pagination__controls {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;

  .apple-pagination--small & {
    gap: 12px;
  }

  .apple-pagination--large & {
    gap: 20px;
  }

  @media (max-width: 768px) {
    order: 1;
    justify-content: center;
    gap: 12px;
  }
}

.apple-pagination__size-changer {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;

  @media (max-width: 568px) {
    display: none;
  }
}

.apple-pagination__size-label {
  color: var(--apple-color-text-secondary);
  font-size: inherit;
}

.apple-pagination__size-select {
  width: 80px;
}

.apple-pagination__jumper {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;

  @media (max-width: 568px) {
    display: none;
  }
}

.apple-pagination__jumper-label {
  color: var(--apple-color-text-secondary);
  font-size: inherit;
}

.apple-pagination__jumper-input {
  width: 60px;
}

.apple-pagination__nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.apple-pagination__pages {
  display: flex;
  align-items: center;
  gap: 4px;
}

.apple-pagination__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  background: var(--apple-color-background-primary);
  border: 1px solid var(--apple-color-separator);
  border-radius: 6px;
  color: var(--apple-color-text-primary);
  font-size: inherit;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  outline: none;
  white-space: nowrap;

  &:hover:not(&--disabled) {
    background: var(--apple-color-background-secondary);
    border-color: var(--apple-color-accent);
    color: var(--apple-color-accent);
  }

  &:active:not(&--disabled) {
    background: var(--apple-color-background-tertiary);
    transform: scale(0.95);
  }

  &:focus-visible {
    box-shadow: 0 0 0 3px var(--apple-color-accent-alpha-low);
  }

  &--current {
    background: var(--apple-color-accent);
    border-color: var(--apple-color-accent);
    color: white;
    cursor: default;

    &:hover {
      background: var(--apple-color-accent);
      border-color: var(--apple-color-accent);
      color: white;
    }
  }

  &--disabled {
    background: var(--apple-color-background-tertiary);
    border-color: var(--apple-color-separator);
    color: var(--apple-color-text-quaternary);
    cursor: not-allowed;
  }

  &--prev,
  &--next {
    svg {
      width: 16px;
      height: 16px;
    }
  }

  .apple-pagination--small & {
    min-width: 28px;
    height: 28px;
    padding: 0 6px;

    &--prev,
    &--next {
      svg {
        width: 14px;
        height: 14px;
      }
    }
  }

  .apple-pagination--large & {
    min-width: 36px;
    height: 36px;
    padding: 0 10px;

    &--prev,
    &--next {
      svg {
        width: 18px;
        height: 18px;
      }
    }
  }
}

.apple-pagination__ellipsis {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  color: var(--apple-color-text-tertiary);
  font-weight: 500;
  user-select: none;

  .apple-pagination--small & {
    min-width: 28px;
    height: 28px;
  }

  .apple-pagination--large & {
    min-width: 36px;
    height: 36px;
  }
}

// 暗色模式
@media (prefers-color-scheme: dark) {
  .apple-pagination__btn--current {
    background: var(--apple-color-accent);
    border-color: var(--apple-color-accent);
  }
}

// 高对比度模式
@media (prefers-contrast: high) {
  .apple-pagination__btn {
    border-width: 2px;
  }

  .apple-pagination__btn--current {
    border-color: var(--apple-color-text-primary);
  }
}

// 减少动画模式
@media (prefers-reduced-motion: reduce) {
  .apple-pagination__btn {
    transition: none;
  }
}

// 移动端适配
@media (max-width: 480px) {
  .apple-pagination__nav {
    gap: 2px;
  }

  .apple-pagination__pages {
    gap: 2px;
  }

  .apple-pagination__btn {
    min-width: 28px;
    height: 28px;
    padding: 0 4px;
    font-size: 12px;
  }

  .apple-pagination__btn--prev,
  .apple-pagination__btn--next {
    span {
      display: none;
    }
  }
}
</style>